package frontend.parser.node.expnode;

import frontend.lexer.token.Token;
import frontend.lexer.token.TokenType;
import frontend.parser.node.Node;
import frontend.parser.node.TokenNode;
import utils.ArrayUtils;

import java.util.ArrayList;

public class UnaryExp extends Node {

    public enum UnaryExpType {
        PRIMARY_EXP, FUNCTION_CALL;
    }
    private UnaryExpType type;

    private ArrayList<TokenType> operators = new ArrayList<>();

    // PRIMARY_EXP
    private PrimaryExp primaryExp;

    // FUNCTION_CALL
    private TokenNode funcIdentTokenNode;
    private FuncRParams funcRParams;
    private ArrayList<Exp> funcRParamsExpList = new ArrayList<>();


    public void addUnaryOp(UnaryOp unaryOp) {
        super.add(unaryOp);
        this.operators.add(unaryOp.getOperator());
    }
    public void addPrimaryExp(PrimaryExp primaryExp) {
        super.add(primaryExp);
        this.type = UnaryExpType.PRIMARY_EXP;
        this.primaryExp = primaryExp;
    }

    public void addIdentTokenNode(TokenNode tokenNode) {
        super.add(tokenNode);
        this.type = UnaryExpType.FUNCTION_CALL;
        this.funcIdentTokenNode = tokenNode;
    }

    public void addFuncRParams(FuncRParams funcRParams) {
        super.add(funcRParams);
        this.funcRParams = funcRParams;
        this.funcRParamsExpList = funcRParams.getExpList();
    }

    public void reverseUnaryOp() {
        this.operators = ArrayUtils.reverse(this.operators);
    }

    public UnaryExpType getType() {
        return type;
    }

    public ArrayList<TokenType> getOperators() {
        return operators;
    }

    public PrimaryExp getPrimaryExp() {
        return primaryExp;
    }

    public TokenNode getFuncIdentTokenNode() {
        return funcIdentTokenNode;
    }

    public FuncRParams getFuncRParams() {
        return funcRParams;
    }

    public ArrayList<Exp> getFuncRParamsExpList() {
        return funcRParamsExpList;
    }

    public String getFuncIdentName() {
        return funcIdentTokenNode.getContent();
    }
    public Token getFuncIdentToken() {
        return funcIdentTokenNode.getToken();
    }

    public boolean hasOperator() {
        return !operators.isEmpty();
    }
}
